package org.enhance.common.util.convert;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.enhance.common.model.bo.geojson.GeoJson;
import org.enhance.common.model.bo.geojson.GeoJsonFeature;
import org.enhance.common.model.bo.geojson.GeoJsonGeometry;
import org.enhance.common.model.po.GeoMultiPolygon;
import org.enhance.common.model.po.GeoPoint;
import org.enhance.common.model.po.GeoPolygon;
import org.enhance.common.util.Assertion;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author JiangGengchao
 * @classname GeoJsonUtil
 * @description
 * @date 2021-11-05
 **/
@Slf4j
public class GeoJsonUtil {
	private GeoJsonUtil() {
		throw new IllegalStateException("Constant class");
	}

	public static GeoMultiPolygon convertNoFlyZoneGeoJson2MultiPolygon(GeoJson noFlyZoneGeoJson) {
		log.info("geojson name:{}, type:{}", noFlyZoneGeoJson.getName(), noFlyZoneGeoJson.getType());
		List<GeoJsonFeature> features = noFlyZoneGeoJson.getFeatures();
		if (CollectionUtils.isNotEmpty(features)) {
			GeoMultiPolygon geoMultiPolygon = new GeoMultiPolygon();
			for (GeoJsonFeature feature : features) {
				GeoJsonGeometry geometry = feature.getGeometry();
				log.info("geojson name:{}, geometry type:{}", noFlyZoneGeoJson.getName(), geometry.getType());
				GeoPolygon polygon = convertGeoJsonCoordinates2Polygon(geometry.getCoordinates());
				if (polygon != null) {
					geoMultiPolygon.addPolygon(polygon);
				}
			}
			return geoMultiPolygon;
		}
		return null;
	}

	private static GeoPolygon convertGeoJsonCoordinates2Polygon(List<List<List<Double>>> coordinates) {
		if (CollectionUtils.isNotEmpty(coordinates)) {
			GeoPolygon geoPolygon = new GeoPolygon();
			for (List<List<Double>> coordinate : coordinates) {
				for (List<Double> doubles : coordinate) {
					geoPolygon.addGeoPoint(BigDecimal.valueOf(doubles.get(0)), BigDecimal.valueOf(doubles.get(1)));
				}
			}
			return geoPolygon;
		}
		return null;
	}

	public static GeoPolygon convertCoordinates2Polygon(List<List<Double>> coordinates) {
		if (CollectionUtils.isNotEmpty(coordinates)) {
			GeoPolygon geoPolygon = new GeoPolygon();
			GeoPoint preGeoPoint = null;
			for (List<Double> doubles : coordinates) {
				GeoPoint geoPoint = new GeoPoint(BigDecimal.valueOf(doubles.get(0)), BigDecimal.valueOf(doubles.get(1)));
				if (preGeoPoint != null) {
					Assertion.isFalse(preGeoPoint.equals(geoPoint), "多边形不允许存在前后相同点");
				}
				preGeoPoint = geoPoint;
				geoPolygon.addGeoPoint(geoPoint);
			}
			return geoPolygon;
		}
		return null;
	}
}
